#include <stdio.h>
unsigned getbits(unsigned x, int p, int n);
unsigned int setbits(unsigned int x,unsigned int p,unsigned int n,unsigned int y);
#define MAGIC_NUMBER 33091
void shotgunPrintUint(const char name[], unsigned int in);

int main()
{
  shotgunPrintUint("return   ",setbits(0xdeadbeef,12,5,0x00000000));
  //  printf("i:%u \t temp:%x \n",-1,temp);

  /** shifting 32 bits out is an overflow condition .*/
  //  unsigned int temp = ~0;
  // unsigned int temp2=temp<<32;
  // printf("\t temp:%x \n",temp2);
  return(0);
}
	   
unsigned int setbits(unsigned int x,unsigned int p,unsigned int n,unsigned int y)
{
  //printf("                      x : %0#10x : p %d : n %d \n",x,p,n);
  unsigned int left = getbits(x,p+n,32-(n+p));   //if position is zero...we just want middle case to handle it.
  //shotgunPrintUint("left    ",left);
  
  unsigned int left_out = ((n+p)<32) ? left << (n+p) :0 ;
  //left is in the right spot
  //shotgunPrintUint("left_out",left_out);
  
  unsigned int middle = getbits(y,p,n);
  //shotgunPrintUint("middle    ",middle);
  unsigned int middle_out = middle << p ;
  //shotgunPrintUint("middle_out",middle_out);
  //shotgunPrintUint("middle_out",middle_out);
  
  unsigned int right_out  = getbits(x,0,p);  // | getbits(y,p,n);
  //shotgunPrintUint("right_out ",right_out);
  
  //printf(" right : %x \n ",right);
  //  unsigned int right_out = right >> (n+p);
  //shotgunPrintUint("right_out",right_out);
  return left_out | middle_out | right_out;
}

/* the problem here is this function is in fact broken due to ~0 << n not
being valid C anymore.
 KNR Bullshit: ~0 << n is not defined in ANSI C 

 KNR getbits:  get n bits from position p 
*/
/* 

   even if it is in K&R C
*/
/* getbits:  get n bits from position p */
unsigned getbits(unsigned x, int p, int n)
{
  //  shotgunPrintUint("test me",0x1);
  //  shotgunPrintUint("test me",0x0);
  //printf ("getbits                x: %0#10x ,p: %d ,n: %d \n",x,p,n);
  unsigned int leftmask,rightmask;
  leftmask = rightmask = ~0;
  //shotgunPrintUint("maxmask    ",leftmask);  
  leftmask = leftmask << p; //find position p
  // shotgunPrintUint("leftmask     ",leftmask);
  int shiftme = 32-(p+n);
  
  rightmask = (shiftme < 32) ? rightmask >> shiftme : 0; //find position p
  //shotgunPrintUint("rightmask     ",rightmask);
  //shotgunPrintUint("shiftme     ",shiftme);

  unsigned int finalmask = leftmask & rightmask;
  
  unsigned int data = x & finalmask;
  // shotgunPrintUint("mask     ",finalmask);  
  //  shotgunPrintUint("data",data);  
  unsigned int outdata = data >> p;
  //shotgunPrintUint("outdata",outdata);  
    
  //unsigned int outdata = (x >> (p-n));
  //  printf(" mask : %x \n ",mask);  
  //shotgunPrintUint("outdata",outdata);
  return outdata; // (x >> (p-n)) & mask;
}

/** 
caution if you printf, padded with 0's, a hex number of exactly 0 it will print
as 0000000000 not 0x00000000
*/
/**
   drop me in if you don't want to use a debugger like GDB to shotgun-debug
   print the value of a uint
 */
void shotgunPrintUint(const char name[], unsigned int in)
{
  printf(name,23423);
  printf("\t\t: %0#10x \n",in);
  return;
}
